package com.murong.ai.chat.domain.text2speech.xfyun;

import cn.xfyun.model.response.TtsResponse;
import cn.xfyun.service.tts.AbstractTtsWebSocketListener;
import cn.xfyun.util.StringUtils;
import com.google.gson.Gson;
import com.murong.ai.chat.infrastructure.utils.PrintUtils;
import lombok.SneakyThrows;
import okhttp3.Response;
import okhttp3.WebSocket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sound.sampled.*;
import java.util.Base64;

public class TTsWebSocketListener extends AbstractTtsWebSocketListener {
    public static final Gson JSON = new Gson();
    private static final Logger logger = LoggerFactory.getLogger(TTsWebSocketListener.class);
    private byte[] bytes = new byte[0];
    private boolean playerFlag=true;

    @SneakyThrows
    public void onMessage(WebSocket webSocket, String text) {
        super.onMessage(webSocket, text);
        TtsResponse resp = (TtsResponse)JSON.fromJson(text, TtsResponse.class);
        if (resp != null) {
            if (resp.getCode() != 0) {
                logger.error("error=>" + resp.getMessage() + " sid=" + resp.getSid());
                this.onBusinessFail(webSocket, resp);
            }
            if (resp.getData() != null) {
                String result = resp.getData().getAudio();
                if (result != null) {
                    byte[] audio = Base64.getDecoder().decode(result);
                    this.bytes = StringUtils.unitByteArray(this.bytes, audio);
                }
                if (resp.getData().getStatus() == 2) {
                    PrintUtils.logLine("Speaking start...");
                    if(this.playerFlag){
                        AudioFormat audioFormat = new AudioFormat(16000, 16, 1, true, false);
                        DataLine.Info speakerInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
                        SourceDataLine speaker = (SourceDataLine) AudioSystem.getLine(speakerInfo);
                        speaker.open(audioFormat);
                        speaker.start();
                        speaker.write(bytes, 0, bytes.length);
                    }
                    webSocket.close(1000, "");
                    PrintUtils.logLine("Speaking end...");
                }
            }
        }

    }

    @Override
    public void onSuccess(byte[] bytes) {

    }

    public void stopRuning(){
        this.playerFlag=false;
    }

    @Override
    public void onFail(WebSocket webSocket, Throwable t, Response response) {

    }

    @Override
    public void onBusinessFail(WebSocket webSocket, TtsResponse response) {

    }
}
